package com.zxc.shortlink.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zxc.shortlink.cache.ShortLinkCache;
import com.zxc.shortlink.component.data.ShortLinkComponentData;
import com.zxc.shortlink.controller.request.LinkMappingRequest;
import com.zxc.shortlink.core.ShortLinkBuildStrategy;
import com.zxc.shortlink.exception.ShortLinkException;
import com.zxc.shortlink.mapper.LinkMappingMapper;
import com.zxc.shortlink.pojo.LinkMapping;
import com.zxc.shortlink.pojo.enums.LinkMappingStateEnum;
import com.zxc.shortlink.service.LinkMappingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author zxc_user
* @date 2022/3/23 22:55
* @version 1.0
* @description LinkMapping服务层实现类
**/
@Slf4j
@Service
public class LinkMappingServiceImpl extends ServiceImpl<LinkMappingMapper, LinkMapping> implements LinkMappingService {

    @Resource
    private ShortLinkComponentData shortLinkComponentData;
    @Resource
    private ShortLinkCache shortLinkCache;
    @Resource
    private ShortLinkBuildStrategy shortLinkBuildStrategy;

    @Override
    public List<String> queryAllShortLink(LinkMappingStateEnum state) {
        if(state == null) {
            return Collections.emptyList();
        }
        QueryWrapper<LinkMapping> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("state", state);
        List<LinkMapping> mappingList = list(queryWrapper);
        return mappingList.stream().filter(Objects::nonNull).map(LinkMapping::getShortLink).collect(Collectors.toList());
    }

    @Override
    public boolean saveLinkMapping(LinkMappingRequest linkMappingRequest) {

        try {
            String originLink = linkMappingRequest.getOriginLink();

            LinkMapping linkMapping = new LinkMapping();
            linkMapping.setState(LinkMappingStateEnum.ENABLE);
            linkMapping.setOriginLink(originLink);
            linkMapping.setShortLink(shortLinkBuildStrategy.build());
            linkMapping.init();
            boolean save = save(linkMapping);
            if(save) {
                //添加到布隆过滤器中
                shortLinkComponentData.addData(linkMapping.getShortLink());
            }
            return save;
        } catch (DuplicateKeyException e) {
            //todo 异常处理
            log.error("创建成功", e);
            return true;
        }
    }

    @Override
    public String getOriginLinkByShortLink(String shortLink) {

        String cacheOriginLink = shortLinkCache.getCacheOriginLink(shortLink);
        if(cacheOriginLink != null) {
            return cacheOriginLink;
        }

        if (!shortLinkComponentData.matches(shortLink)) {
            throw new ShortLinkException("该链接不在当前系统中");
        }

        QueryWrapper<LinkMapping> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("short_link", shortLink);

        List<LinkMapping> mappingList = list(queryWrapper);
        if(mappingList.isEmpty()) {
            throw new ShortLinkException("该链接不在当前系统中");
        }

        //设置缓存
        shortLinkCache.setCache(mappingList.get(0));

        //todo 排查处理
        return mappingList.get(0).getOriginLink();
    }
}
